//
//  SAWebViewController.swift
//  SevenAISDK
//
//  Created by 七块 on 2025/7/7.
//
import UIKit
import WebKit
import AudioToolbox

public class SAWebViewController: UIViewController {
    // 纯代码创建UI元素
    private var webView: WKWebView!
    // 要加载的网页URL
    public var webPageURL: String = "https://www.baidu.com" // 设置默认URL或者通过外部设置
    
    let promission = PermissionManager()

    public override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        webView.frame = view.bounds   // 或者如果需要调整，可以设置成view.bounds
    }
    public override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
        loadOnlinePage()
    }
    // MARK: - UI Setup
    private func setupUI() {
        view.backgroundColor = UIColor.white
        title = "H5与iOS通信"
        // 创建WebView配置
        let configuration = WKWebViewConfiguration()
        // 注册message handler
        configuration.userContentController.add(self, name: H5Command.requestAudioPermission.rawValue)
       configuration.userContentController.add(self, name: H5Command.requestFilePermission.rawValue)
       configuration.userContentController.add(self, name: H5Command.requestConnectDevice.rawValue)
       configuration.userContentController.add(self, name: H5Command.onToyControlCommand.rawValue)
       configuration.userContentController.add(self, name: H5Command.onPaymentCancel.rawValue)
       configuration.userContentController.add(self, name: H5Command.onPaymentFailed.rawValue)
       configuration.userContentController.add(self, name: H5Command.onPaymentSuccess.rawValue)
       configuration.userContentController.add(self, name: H5Command.onWebsocketConnected.rawValue)
       configuration.userContentController.add(self, name: H5Command.onWebsocketConnectFailed.rawValue)
       configuration.userContentController.add(self, name: H5Command.onWebsocketDisConnected.rawValue)
       configuration.userContentController.add(self, name: H5Command.requestConsume.rawValue)
       configuration.userContentController.add(self, name: H5Command.useCustomerPayment.rawValue)
        configuration.userContentController.add(self, name: H5Command.closeH5Page.rawValue)
        // 创建WebView
        webView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height), configuration: configuration)
        webView.navigationDelegate = self
        view.addSubview(webView)
    }
    private func loadOnlinePage(){
        // 判断是否为在线网页URL
         if webPageURL.lowercased().hasPrefix("http://") || webPageURL.lowercased().hasPrefix("https://") {
             // 加载在线网页
             print("正在加载在线网页: \(webPageURL)")
             guard let finalUrl = URL(string: webPageURL) else {
                 print("无效的URL: \(webPageURL)")
                 return
             }
             let request = URLRequest(url: finalUrl)
             webView.load(request)
         }else{
             print("在线网页地址错误: \(webPageURL)")
         }
    }
}
// MARK: - WKScriptMessageHandler
extension SAWebViewController: WKScriptMessageHandler {
    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {        
        switch message.name{
        case H5Command.requestAudioPermission.rawValue:
            print("录音权限请求,\(message.body)")
            handleAudioPermissionRequest(data: message.body)
        case H5Command.requestFilePermission.rawValue:
            print("文件权限请求,\(message.body)")
            handleFilePermissionRequest(data: message.body)
        case H5Command.requestConnectDevice.rawValue:
            print("连接设备请求,\(message.body)")
            handleConnectDeviceRequest(data: message.body)
        case H5Command.onToyControlCommand.rawValue:
            print("控制玩具指令,\(message.body)")
            handleToyControlCommand(data: message.body)
        case H5Command.onPaymentSuccess.rawValue:
            print("支付成功,\(message.body)")
        case H5Command.onPaymentFailed.rawValue:
            print("支付失败,\(message.body)")
        case H5Command.onPaymentCancel.rawValue:
            print("支付取消,\(message.body)")
        case H5Command.onWebsocketConnected.rawValue:
            print("WebSocket连接成功,\(message.body)")
        case H5Command.onWebsocketConnectFailed.rawValue:
            print("WebSocket连接失败,\(message.body)")
        case H5Command.onWebsocketDisConnected.rawValue:
            print("WebSocket断开连接,\(message.body)")
        case H5Command.requestConsume.rawValue:
            guard let dict = message.body as? [String:Any] else { return }
            guard let data = dictToModel(dict) else {return }
            SevenAI.shared.payMent?.requestConsume(data: data)
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+5) {
                //模拟扣款结果
                self.setUserConsumeComplete()
            }
        case H5Command.useCustomerPayment.rawValue:
            guard let dict = message.body as? [String:Any] else { return }
            guard let data = dictToModel(dict) else { return }
            SevenAI.shared.payMent?.useConstomerRecharge(data: data)
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+5) {
                //模拟支付结果
                self.setUserPaymentComplete()
            }
        case H5Command.closeH5Page.rawValue:
            print("关闭页面")
            back()
        case H5Command.requestHandleChatConsumeRecords.rawValue:
            XMLog.logs("收到requestHandleChatConsumeRecords事件")
            break
        case H5Command.goBack.rawValue:
            XMLog.logs("收到goBack事件")
            if webView.canGoBack {
                webView.goBack()
            }
            break
        default:
            print("未处理的消息类型: \(message.name)")
        }
    }
    // 字典转模型
    func dictToModel(_ dict: [String: Any]) -> ConsumeData? {
        guard let data = try? JSONSerialization.data(withJSONObject: dict) else { return nil }
        return try? JSONDecoder().decode(ConsumeData.self, from: data)
    }
    // 在SDK提供的视图控制器中
    public func close(animated: Bool, completion: (() -> Void)? = nil) {
        self.presentingViewController?.dismiss(animated: animated, completion: completion)
    }
    func back(){
        let alert = UIAlertController.init(title: "提示", message: "你确定要退出H5界面吗", preferredStyle: .alert)
        let ok = UIAlertAction(title: "确定", style: .default) {[weak self] _ in
            guard let Myself = self else { return }
            Myself.close(animated: true)
        }
        let cancel = UIAlertAction(title: "取消", style: .cancel) { _ in
            
        }
        alert.addAction(ok)
        alert.addAction(cancel)
        present(alert, animated: true)
    }
    func backPage(){
        DispatchQueue.main.async {
            self.dismiss(animated: true, completion: nil)
        }
    }
    
    // MARK: - 具体的消息处理方法
    private func handleAudioPermissionRequest(data: Any) {
        promission.requestPermission(.microphone) { result in
            print("请求结果=\(result)")
        }
        // 这里可以添加具体的录音权限处理逻辑
    }
    private func handleFilePermissionRequest(data: Any) {
        // 这里可以添加具体的文件权限处理逻辑
    }
    private func handleConnectDeviceRequest(data: Any) {
        if SaveTools.manager.deviceStatus == .DISCONNECTED {
            guard let manager = SevenAI.shared.toyManger else {
                XMLog.logs("没有设置玩具回调,请设置")
                return
            }
            // 这里可以添加具体的设备连接逻辑
            manager.CallBackListener(.requestConnectDevice)
        }
        setDeviceStatus()
    }
    private func handleToyControlCommand(data: Any) {
        XMLog.logs("指令信息=\(data)")
        guard let dict = data as? [String:Any] else { return }
        guard let cmd = dict["cmd"] as? String else { return }
        guard let manager = SevenAI.shared.toyManger else {
            XMLog.logs("没有设置玩具回调,请设置")
            return
        }
        if let command = ToyControlCommand.from(code: cmd) {
            XMLog.logs("匹配的枚举: \(command)") // 输出：START_WORK
            manager.CallBackListener(.onToyControlCommand(command: command))
        } else {
            XMLog.logs("无效指令")
        }
    }
}

// MARK: - WKNavigationDelegate
extension SAWebViewController: WKNavigationDelegate {
    public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        print("H5页面加载完成")
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2) {
            self.setJwtToken()
            self.setDeviceInfo()
            self.setDeviceStatus()
        }
    }
    public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        print("H5页面加载失败: \(error)")
    }
}
extension SAWebViewController{
    
    // 定义泛型编码函数（支持任何遵循 Codable 的类型）
    func encodeToJSON<T: Codable>(_ object: T) -> String? {
        let encoder = JSONEncoder()
        do {
            let jsonData = try encoder.encode(object)
            return String(data: jsonData, encoding: .utf8)
        } catch {
            print("编码失败: \(error)")
            return nil
        }
    }
    ///字典转json字符串
    func getJsonStringFromDict(_ dict:[String:Any]) -> String{
        guard let data:Data = try? JSONSerialization.data(withJSONObject: dict) else { return String() }
        guard let jsonString = String(data: data, encoding: String.Encoding.utf8) else { return String() }
        return jsonString
    }
    /// 设置jwtToken
    func setJwtToken(){
        let info = SaveTools.manager.loginInfo
        guard let _ = info.token else {
            SevenAI.shared.sdkListener(.setSDKError(ErrorCode.E005.value, "请设置用户token"))
            return
        }
        guard let _ = info.appId else {
            SevenAI.shared.sdkListener(.setSDKError(ErrorCode.E005.value, "请设置appID"))
            return
        }
        guard let _ = info.userId else {
            SevenAI.shared.sdkListener(.setSDKError(ErrorCode.E005.value, "请设置userId"))
            return
        }
        guard let jsonStr = encodeToJSON(SaveTools.manager.loginInfo) else {
            return
        }
        XMLog.logs("设置token信息到h5=\(jsonStr)")
        sendMsgToJs(eventName: JSEventName.setToken.rawValue, json: jsonStr)
    }
    func setDeviceInfo(){
        guard let deviceInfo = SaveTools.manager.deviceInfo else {
            SevenAI.shared.sdkListener(.setSDKError(ErrorCode.E005.value, "请设置设备信息"))
            return
        }
        var json:[String:Any] = [:]
        json["btName"] = deviceInfo.btName
        json["deviceSn"] = deviceInfo.deviceSn
        json["isBleDevice"] = true
        let types = deviceInfo.motorTypes.map { type in
            type.rawValue
        }
        json["motorTypes"] = types
        let jsonStr = getJsonStringFromDict(json)
        XMLog.logs("设置设备信息到h5=\(jsonStr)")
        sendMsgToJs(eventName: JSEventName.setDeviceInfo.rawValue, json: jsonStr)
    }
    func setDeviceStatus(){
        guard let status = SaveTools.manager.deviceStatus else {
            SevenAI.shared.sdkListener(.setSDKError(ErrorCode.E005.value, "请设置设备状态"))
            return
        }
        var json:[String:Any] = [:]
        json["status"] = status == .CONNECTED ? 1 : 0
        let jsonStr = getJsonStringFromDict(json)
        sendMsgToJs(eventName: JSEventName.setDeviceStatus.rawValue, json: jsonStr)
    }
    /// 支付成功
    func setUserPaymentComplete() {
        var json:[String:Any] = [:]
        json["result"] = Bool.random()
        let jsonStr = getJsonStringFromDict(json)
        sendMsgToJs(eventName: JSEventName.paymentResult.rawValue, json: jsonStr)
    }
    /// 扣款成功
    func setUserConsumeComplete() {
        var json:[String:Any] = [:]
        json["result"] = Bool.random()
        let jsonStr = getJsonStringFromDict(json)
        sendMsgToJs(eventName: JSEventName.deductionResult.rawValue, json: jsonStr)
    }
    func sendMsgToJs(eventName:String,json:String){
        let msg = String(format: "%@('%@')",eventName,json)
        self.webView.evaluateJavaScript(msg) { response, error in
            XMLog.logs("发送了\(eventName)事件,结果是=\(error.debugDescription)")
        }
    }
}
